package com.kanavi.stand.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kanavi.stand.constant.RedisConstant;
import com.kanavi.stand.entity.UserStandInfo;
import com.kanavi.stand.mapper.UserStandInfoMapper;
import com.kanavi.stand.service.UserStandInfoService;
import com.kanavi.stand.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;

/**
 * 用户小程序停留时长记录表 服务实现类
 *
 * @author tanghailan
 * @since 2020-10-22
 */
@Service
@Slf4j
public class UserStandInfoServiceImpl extends ServiceImpl<UserStandInfoMapper, UserStandInfo>
    implements UserStandInfoService {

  @Resource private RedisUtil redisUtil;

  @Override
  public void putUserStand(String userId, Long standStart, Long standEnd) {
    // 处理时间
    Date standStartTime = DateUtil.date(standStart * 1000);
    Date standEndTime = DateUtil.date(standEnd * 1000);
    log.info("standStartTime为：" + standStartTime);
    log.info("standEndTime为：" + standEndTime);
    // 判断是否是同一天
    boolean isSameDay = DateUtil.isSameDay(standStartTime, standEndTime);
    if (isSameDay) {
      log.info("用户停留时间上报起止时间是同一天 userId={}", userId);
      this.sameDateSave(standStartTime, standEndTime, userId);
    } else {
      this.doSaveNotSameDay(standStartTime, standEndTime, userId);
      log.info("用户停留时间上报起止时间不是同一天 userId={}", userId);
    }
  }

  /**
   * 时间在同一天
   *
   * @param startDateTime
   * @param endDateTime
   */
  private void sameDateSave(Date startDateTime, Date endDateTime, String userId) {
    // 使用截止时间格式化为 yyyyMMdd
    // 注：因为可能存在跨天所以使用 截止时间
    String reqDate = DateUtil.formatDateTime(endDateTime);
    log.info("当前统计时间区间 reqDate => {}", reqDate);
    // 计算间隔秒数
    long second = DateUtil.betweenMs(startDateTime, endDateTime) / 1000;
    log.info("计算间隔秒数 second => {}", second);
    // hash缓存key
    String hashKey = RedisConstant.USER_STAND_HASH_KEY.concat(reqDate);
    log.debug("用户小程序停留时长统计Hash Key => {}", hashKey);
    redisUtil.hIncr(hashKey, userId, second);

    // list缓存key
    String listKey = RedisConstant.USER_STAND_LIST_KEY.concat(reqDate);
    log.debug("用户小程序停留时长统计List Key => {}", listKey);
    redisUtil.lSet(listKey, userId, 0);
  }

  /**
   * 时间非同一天
   *
   * @param startDateTime
   * @param endDateTime
   */
  private void doSaveNotSameDay(Date startDateTime, Date endDateTime, String userId) {
    // 计算起点的结束时间 当天的 23:59:59
    Date startDayEndDate = DateUtil.endOfDay(startDateTime);
    // 保存前一天的停留时长
    this.sameDateSave(startDayEndDate, endDateTime, userId);
    // 保存当天的停留时长
    this.sameDateSave(startDateTime, startDayEndDate, userId);
  }
}
